package com.linsir.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.camunda.bpm.engine.spring.SpringProcessEngineConfiguration;
import org.camunda.bpm.engine.spring.SpringProcessEngineServicesConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;
import java.io.IOException;
import java.sql.SQLException;

/**
 * @ProjectName:linsir-lin
 * @Package:com.linsir.config
 * @Title: CamundaConfigguration
 * @Description: 流程引擎配置
 * @Create:2021/6/26 12:07 by @author:Linsir
 * @Update:2021/6/26 12:07 by @author:Linsir
 * @UpdateRemark: 初始创建
 * @Version: 1.0.0
 */
@Configuration
@Import( SpringProcessEngineServicesConfiguration.class )
public class CamundaConfiguration {


    @Value("${camunda.bpm.history-level:none}")
    private String historyLevel;

    @Value("${camunda.datasource.url}")
    private String url;

    @Value("${camunda.datasource.username}")
    private String username;

    @Value("${camunda.datasource.password}")
    private String password;

    @Value("${camunda.datasource.driverClassName}")
    private String driverClass;

    @Value("${spring.datasource.initialSize}")
    private int initialSize;

    @Value("${spring.datasource.minIdle}")
    private int minIdle;

    @Value("${spring.datasource.maxActive}")
    private int maxActive;

    @Value("${spring.datasource.maxWait}")
    private int maxWait;

    @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
    private int timeBetweenEvictionRunsMillis;

    @Value("${spring.datasource.minEvictableIdleTimeMillis}")
    private int minEvictableIdleTimeMillis;

    @Value("${spring.datasource.validationQuery}")
    private String validationQuery;

    @Value("${spring.datasource.testWhileIdle}")
    private boolean testWhileIdle;

    @Value("${spring.datasource.testOnBorrow}")
    private boolean testOnBorrow;

    @Value("${spring.datasource.testOnReturn}")
    private boolean testOnReturn;

    @Value("${spring.datasource.poolPreparedStatements}")
    private boolean poolPreparedStatements;

    @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
    private int maxPoolPreparedStatementPerConnectionSize;

    @Value("${spring.datasource.filters}")
    private String filters;

    @Value("{spring.datasource.connectionProperties}")
    private String connectionProperties;


    @Autowired
    private ResourcePatternResolver resourceLoader;

    /**
     * 配置中的重点：
     * 如果您要配置多个数据源，并且不想在流程引擎中使用@Primary数据源，
     * 则可以创建一个名称为camundaBpmDataSource的单独数据源，该数据源将自动与Camunda连接
     * 我们暂时不使用默认的斑斑
     * @return
     */
    @Bean(name = "camundaBpmDataSource")
    @Primary
    public DataSource camundaDataSource()
    {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setDriverClassName(driverClass);

        //具体配置
        dataSource.setInitialSize(initialSize);
        dataSource.setMinIdle(minIdle);
        dataSource.setMaxActive(maxActive);
        dataSource.setMaxWait(maxWait);
        dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        dataSource.setValidationQuery(validationQuery);
        dataSource.setTestWhileIdle(testWhileIdle);
        dataSource.setTestOnBorrow(testOnBorrow);
        dataSource.setTestOnReturn(testOnReturn);


        try {
            dataSource.setFilters("stat,wall,slf4j");
        } catch (SQLException e) {
            e.printStackTrace();
        }
        dataSource.setPoolPreparedStatements(poolPreparedStatements);
        dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
        try {
            dataSource.setFilters(filters);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        dataSource.setConnectionProperties(connectionProperties);
        return dataSource;

    }



    @Bean(value = "transactionManager")
    public PlatformTransactionManager transactionManager(@Qualifier("camundaBpmDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean
    public SpringProcessEngineConfiguration springProcessEngineConfiguration(@Qualifier("transactionManager") PlatformTransactionManager transactionManager,
                                                                             @Qualifier("camundaBpmDataSource") DataSource dataSource) throws IOException {
        SpringProcessEngineConfiguration springProcessEngineConfiguration = new SpringProcessEngineConfiguration();
        springProcessEngineConfiguration.setDataSource(dataSource);
        springProcessEngineConfiguration.setTransactionManager(transactionManager);
        springProcessEngineConfiguration.setDatabaseSchemaUpdate("true");
        springProcessEngineConfiguration.setHistory(historyLevel);



        springProcessEngineConfiguration.setJobExecutorActivate(true);
        springProcessEngineConfiguration.setMetricsEnabled(false);

        // deploy all processes from folder 'processes'
        Resource[] resources = resourceLoader.getResources("classpath:/processes/*.bpmn");
        springProcessEngineConfiguration.setDeploymentResources(resources);

        return  springProcessEngineConfiguration;
    }
}
